home *** CD-ROM | disk | FTP | other *** search
/ Gekkan Dennou Club 145 / Gekkan Dennou Club - 2000.6 Vol. 145 (Japan).7z / Gekkan Dennou Club - 2000.6 Vol. 145 (Japan) (Track 1).bin / tools / sharp / sxwork3.lzh / サンプル実用編 / ペイント / GPAINT.C next >
Text File  |  1994-03-10  |  28KB  |  896 lines

  1. /******************************************************************************
  2.  *    gpaint.c:    ペイント編集の処理関数
  3.  ******************************************************************************
  4.  *    Workroom SX-68K Sample Program Copyright 1994 SHARP
  5.  */
  6. #include <stdio.h>
  7. #include <string.h>
  8. #include <sxmemory.h>        /* メモリマンを利用するときに必要    */
  9. #include <console.h>        /* コンソール系マネージャを利用するときに必要 */
  10. #include <event.h>        /* イベントマンを利用するときに必要    */
  11. #include <sxgraph.h>        /* グラフ系マネージャを利用するときに必要 */
  12. #include <control.h>        /* コントロールマンを利用するときに必要    */
  13. #include <dialog.h>        /* ダイアログマンを利用するときに必要    */
  14. #include <text.h>        /* テキストマンを利用するときに必要    */
  15. #include "gpaint.h"        /* このプログラム固有のヘッダファイル    */
  16.  
  17. /******************************************************************************
  18.  *    paintFig():    図形でのペイント処理
  19.  ******************************************************************************
  20.  *    引数:    ComVal *pcv    共通変数へのポインタ
  21.  *        LPoint lpt    マウスレフトダウン時の座標
  22.  */
  23. void paintFig(ComVal *pcv, LPoint lpt)
  24. {
  25.  
  26.     Point npt, opt, wpt;
  27.     Rect rc;
  28.  
  29.     /* メインウィンドウをグラフィックタイプでカレントグラフにする */
  30.     setGraph(pcv->windowPtr, G_GRP);
  31.     /* ペンサイズを設定する */
  32.     OldPS.x_y = GMPenSize(pcv->penSize.x_y);
  33.     OldFC = GMForeColor(15);    /* パレット番号を15にする    */
  34.     OldPM = GMPenMode(G_XOR);    /* ペンモードをXORにする    */
  35.  
  36.     /* ラバーバンドのための初期のレクタングルを設定する */
  37.     rc.l.l_t = lpt;
  38.     rc.l.r_b = lpt;
  39.  
  40.     drawFig(pcv, &rc);        /* ラバーバンドを表示する    */
  41.     opt.x_y = lpt;
  42.     npt.x_y = lpt;
  43.     while (EMLStill()) {
  44.         /* マウスが移動された場合のみラバ-バンドを表示する */
  45.         if (opt.x_y != npt.x_y) {
  46.             /* 前回のラバーバンドを消して */
  47.             drawFig(pcv, &rc);
  48.             if (pcv->toolKind == 0 && pcv->toolStat[0] == 0) {
  49.                 /* 直線のときは終点を調節しセットする */
  50.                 wpt = npt;
  51.                 ajustEndPoint(lpt, &wpt, &pcv->pictSize);
  52.                 rc.l.r_b = wpt.x_y;
  53.             } else
  54.                 /* 直線以外はレクタングルを調節する */
  55.                 makeRect(lpt, npt.x_y, &pcv->pictSize, &rc);
  56.             /* 再度ラバーバンドを表示する */
  57.             drawFig(pcv, &rc);
  58.  
  59.         }
  60.         opt = npt;
  61.         /* マウスの現在位置を取得する */
  62.         npt.x_y = EMMSLoc();
  63.     }
  64.     /* ラバーバンドを消去する */
  65.     drawFig(pcv, &rc);
  66.  
  67.     /* 何か描画されたなら */
  68.     if (lpt != npt.x_y)
  69.         /* UNDOのためにデータをセーブする */
  70.         saveDataForUndo(pcv);
  71.  
  72.     /* フォアグラウンドカラーを元に戻す */
  73.     GMForeColor(OldFC);
  74.     /* ペンモードを元に戻す */
  75.     GMPenMode(OldPM);
  76.  
  77.     /* ビッツを使用するためにメモリをロックする */
  78.     GMLockBits(pcv->offBitsHdl[pcv->offIdx]);
  79.  
  80.     /* オフスクリーン用グラフをカレントグラフにする */
  81.     GMSetGraph(&pcv->offGraph);
  82.     pcv->offGraph.bmap = &(*pcv->offBitsHdl[pcv->offIdx])->bmap;
  83.  
  84.     /* フォア/バックグラウンドカラーをセットする */
  85.     setFBColor(pcv);
  86.     GMPenSize(pcv->penSize.x_y);    /* ペンサイズを設定する        */
  87.     /* オフスクリーンに描画する */
  88.     drawFig(pcv, &rc);
  89.  
  90.     /* メインウィンドウをグラフィックタイプでカレントグラフにする */
  91.     setGraph(pcv->windowPtr, G_GRP);
  92.     /* フォア/バックグラウンドカラーをセットする */
  93.     setFBColor(pcv);
  94.     GMPenSize(pcv->penSize.x_y);    /* ペンサイズを設定する        */
  95.     /* メイングラフにも直接描く*/
  96.     drawFig(pcv, &rc);
  97.  
  98.     /* ビッツのメモリをアンロックする */
  99.     GMUnlockBits(pcv->offBitsHdl[pcv->offIdx]);
  100.  
  101.     /* フォア/バックグラウンドカラーを元に戻す */
  102.     GMForeColor(OldFC);
  103.     GMBackColor(OldBC);
  104.     /* ペンモードを元に戻す */
  105.     GMPenMode(OldPM);
  106.     /* ペンサイズを元に戻す */
  107.     GMPenSize(OldPS.x_y);
  108.     /* 何か描画されたか? */
  109.     if (lpt != npt.x_y && !pcv->editFlag)
  110.         pcv->editFlag = TRUE;    /* 編集フラグをセットする    */
  111. }
  112.  
  113. /******************************************************************************
  114.  *    drawFig():    実際の図形表示処理
  115.  ******************************************************************************
  116.  *    引数:    ComVal *pcv    共通変数へのポインタ
  117.  *        Rect *prc    描画するレクタングルへのポインタ
  118.  *    注釈:
  119.  *    指定の図形を指定の座標を用いて表示する。
  120.  *    リージョンについてはラバーバンド表示のときのみ対応。
  121.  */
  122. void drawFig(ComVal *pcv, Rect *prc)
  123. {
  124.     switch (pcv->toolStat[pcv->toolKind]) {
  125.     case 0:                /* 直線            */
  126.     case 1:                /* ペン            */
  127.     case 5:                /* リージョン、リージョン塗りつぶし */
  128.         /* ラインの描画を行う */
  129.         GMMove(prc->l.l_t);
  130.         GMLine(prc->l.r_b);
  131.         break;
  132.     case 2:                /* 長方形、長方形塗りつぶし    */
  133.         if (pcv->toolKind == 0)
  134.             GMFrameRect(prc);
  135.         else if (pcv->toolKind == 1)
  136.             GMFillRect(prc);
  137.         break;
  138.     case 3:                /* 面取り長方形、面取り長方形塗りつぶし */
  139.         if (pcv->toolKind == 0)
  140.             GMFrameRRect(prc, pcv->radius.x_y);
  141.         else if (pcv->toolKind == 1)
  142.             GMFillRRect(prc, pcv->radius.x_y);
  143.         break;
  144.     case 4:                /* 円、円塗りつぶし    */
  145.         if (pcv->toolKind == 0)
  146.             GMFrameOval(prc);
  147.         else if (pcv->toolKind == 1)
  148.             GMFillOval(prc);
  149.         break;
  150.     }
  151. }
  152.  
  153. /******************************************************************************
  154.  *    paintRgn():    リージョンでのペイント処理
  155.  ******************************************************************************
  156.  *    引数:    ComVal *pcv    共通変数へのポインタ
  157.  *        LPoint lpt    マウスレフトダウン時の座標
  158.  */
  159. void paintRgn(ComVal *pcv, LPoint lpt)
  160. {
  161.     int ct;
  162.     unsigned long clickTime;
  163.     unsigned long DblClickT;
  164.     Point npt, opt, bpt, wpt;
  165.     Rect rc;
  166.     Event ev;
  167.  
  168.     struct {
  169.         Point pt[500];    /* リージョン点データ    */
  170.     } **hRgn;
  171.  
  172.     /* UNDOのためにデータをセーブする */
  173.     saveDataForUndo(pcv);
  174.  
  175.     /* メインウィンドウをグラフィックタイプでカレントグラフにする */
  176.     setGraph(pcv->windowPtr, G_GRP);
  177.  
  178.     OldPS.x_y = GMPenSize(pcv->penSize.x_y); /* ペンサイズを設定する */
  179.     OldFC = GMForeColor(15);    /* パレット番号を15にする    */
  180.     OldPM = GMPenMode(G_XOR);    /* ペンモードをXORにする    */
  181.     DblClickT = EMDClickGet();    /* ダブルクリックの既定値を取得する */
  182.     /* マウスレフトダウンイベント発生時の時間をセットする */
  183.     clickTime = pcv->event.ts.when;
  184.  
  185.     /* リージョンの座標データ用ハンドルを確保する */
  186.     hRgn = MMChHdlNew(2048);
  187.     if (hRgn == NULL) {
  188.         DMError(D_CONFIRM, "メモリが確保できません。");
  189.         return;
  190.     }
  191.  
  192.     /* ラバーバンドのための初期のレクタングルを設定する */
  193.     rc.l.l_t = lpt;
  194.     rc.l.r_b = lpt;
  195.  
  196.     drawFig(pcv, &rc);        /* ラバーバンドを表示する    */
  197.     ct = 0;
  198.     (*hRgn)->pt[ct++].x_y = lpt;
  199.     npt.x_y = lpt;
  200.     opt.x_y = lpt;
  201.     bpt.x_y = lpt;
  202.     wpt.x_y = lpt;
  203.     while (1) {
  204.         /* イベントキューからすべてのイベントを取り出す。そうしないと、
  205.            イベントが溜まって途中でマウスレフトダウンイベントが受け取れ
  206.            なくなる */
  207.         if (EMGet(EM_EVERY, &ev) && ev.what == E_MSLDOWN) {
  208.             /* マウスレフトダウンイベントがあったとき */
  209.             if (ev.when <= clickTime + DblClickT
  210.              && (*hRgn)->pt[ct - 1].x_y == npt.x_y && ct >= 3) {
  211.                 /* ダブルクリックでかつクリック座標が前回クリッ
  212.                    クされた座標と違っていて3点以上入力されてい
  213.                    たならリージョン座標のセットを終了する */
  214.                 drawFig(pcv, &rc); /* 最後の仮表示を消去する */
  215.                 break;
  216.             } else {
  217.                 /* マウスレフトダウンイベント発生時の時間をセットする */
  218.                 clickTime = ev.when;
  219.                 rc.l.l_t = wpt.x_y;
  220.                 (*hRgn)->pt[ct++] = wpt;
  221.                 bpt = wpt;
  222.                 if (ct >= 512) {
  223.                     DMError(D_CONFIRM, "これ以上座標は指定できません。\r"
  224.                                "リージョンの登録を終了します。");
  225.                     break;
  226.                 }
  227.                 drawFig(pcv, &rc);
  228.             }
  229.             /* 先行するマウスレフトアップイベントを取り除く。これが
  230.                ないと、途中でマウスダウンイベントが拾えなくなる */
  231.             EMLWait();
  232.         }
  233.         /* マウスが移動された場合のみラバ-バンドを表示する */
  234.         if (opt.x_y != npt.x_y) {
  235.             /* 前回のラバーバンドを消して */
  236.             drawFig(pcv, &rc);
  237.             wpt = npt;
  238.             /* ウィンドウ内におさまる様に座標を調整する */
  239.             ajustEndPoint(bpt.x_y, &wpt, &pcv->pictSize);
  240.             rc.l.r_b = wpt.x_y;
  241.             /* 再度ラバーバンドを表示する */
  242.             drawFig(pcv, &rc);
  243.         }
  244.  
  245.         opt = npt;
  246.         /* マウスの現在位置を取得する */
  247.         npt.x_y = EMMSLoc();
  248.  
  249.     }
  250.  
  251.     /* ビッツを使用するためにメモリをロックする */
  252.     GMLockBits(pcv->offBitsHdl[pcv->offIdx]);
  253.  
  254.     /* データよりリージョンを作成しオフスクリーンに描画する */
  255.     if (!makeRgn(pcv, (*hRgn)->pt, ct, &rc)) {
  256.         /* ビッツのメモリをアンロックする */
  257.         GMUnlockBits(pcv->offBitsHdl[pcv->offIdx]);
  258.         return;
  259.     }
  260.  
  261.     /* メインウィンドウをグラフィックタイプでカレントグラフにする */
  262.     setGraph(pcv->windowPtr, G_GRP);
  263.  
  264.     /* オフスクリーンからコピーして描画する */
  265.     GMTransImg(&(*pcv->offBitsHdl[pcv->offIdx])->bmap, pcv->windowPtr->graph.bmap, &rc, &rc);
  266.  
  267.     /* ビッツのメモリをアンロックする */
  268.     GMUnlockBits(pcv->offBitsHdl[pcv->offIdx]);
  269.  
  270.     /* リージョンの座標データ用ハンドルを解放する */
  271.     MMHdlDispose(hRgn);
  272.  
  273.     /* ペンサイズを元に戻す */
  274.     GMPenSize(OldPS.x_y);
  275.  
  276.     /* 描画終了処理 */
  277.     if (!pcv->editFlag)        /* まだ編集されてないか?    */
  278.         pcv->editFlag = TRUE;    /* 編集フラグをセットする    */
  279. }
  280.  
  281. /******************************************************************************
  282.  *    makeRgn():    与えられたデータからリージョン図形の作成および描画を行う
  283.  ******************************************************************************
  284.  *    引数:    ComVal *pcv    共通変数へのポインタ
  285.  *        Point *ptt    リージョン用の座標テーブルへのポインタ
  286.  *        int ct        リージョン用の座標の個数
  287.  *        Rect *prc    作成されたリージョンを囲むレクタングルを格納す
  288.  *                るポインタ
  289.  *    戻り値:    BOOLEAN        = TRUE:  作成成功
  290.  *                = FALSE: 作成失敗
  291.  *    注釈:    リージョン図形の登録および描画処理を行う。
  292.  */
  293. BOOLEAN makeRgn(ComVal *pcv, Point *ptt, int ct, Rect *prc)
  294. {
  295.     int i, errCode;
  296.     Region **rgnHdl;
  297.  
  298.     /* リージョンの仮表示の消去を行う */
  299.     /* 表示位置をデータの先頭に設定する */
  300.     GMMove(ptt[0].x_y);
  301.     /* データを元に仮表示を消去する */
  302.     for (i = 1; i < ct; i++)
  303.         GMLine(ptt[i].x_y);
  304.     /* フォアグラウンドカラーを元に戻す */
  305.     GMForeColor(OldFC);
  306.     /* ペンモードを元に戻す */
  307.     GMPenMode(OldPM);
  308.  
  309.     /* 待ち状態を示すマウスポインタを表示する */
  310.     EMEnCross();
  311.     /* オフスクリーン用グラフをカレントグラフにする */
  312.     GMSetGraph(&pcv->offGraph);
  313.     pcv->offGraph.bmap = &(*pcv->offBitsHdl[pcv->offIdx])->bmap;
  314.  
  315.     /* フォア/バックグラウンドカラーをセットする */
  316.     setFBColor(pcv);
  317.     GMPenSize(pcv->penSize.x_y);    /* ペンサイズを設定する        */
  318.  
  319.     /* 空のリージョンを作成する */
  320.     rgnHdl = GMNewRgn();
  321.     if (rgnHdl == NULL) {
  322.         /* 待ち状態を示すマウスポインタを元に戻す */
  323.         EMDeCross();
  324.         DMError(D_CONFIRM, "メモリが確保できません。");
  325.         return FALSE;
  326.     }
  327.     /* リージョンの記録開始 */
  328.     GMOpenRgn();
  329.     /* 表示位置をデータの先頭に設定する */
  330.     GMMove(ptt[0].x_y);
  331.     /* リージョン図形の記録を行う */
  332.     for (i = 1; i < ct; i++)
  333.         GMLine(ptt[i].x_y);
  334.     /* 始点データと結ぶ */
  335.     GMLine(ptt[0].x_y);
  336.     /* リージョンの記録終了 */
  337.     errCode = GMCloseRgn(rgnHdl);
  338.     if (errCode < 0) {
  339.         GMDisposeRgn(rgnHdl);    /* リージョンハンドルを解放する    */
  340.         /* 待ち状態を示すマウスポインタを元に戻す */
  341.         EMDeCross();
  342.         DMError(D_CONFIRM, "メモリが不足しています。\r"
  343.                    "リージョンの記録ができません。");
  344.         return FALSE;
  345.     }
  346.     /* リージョンを囲むレクタングルの座標をprcに設定する */
  347.     *prc = (*rgnHdl)->bounds;
  348.  
  349.     /* 入力されたリージョンをオフスクリーンに描画する */
  350.     if (pcv->toolKind == 0)
  351.         GMFrameRgn(rgnHdl);
  352.     else
  353.         GMFillRgn(rgnHdl);
  354.  
  355.     GMDisposeRgn(rgnHdl);        /* リージョンハンドルを解放する    */
  356.     /* 待ち状態を示すマウスポインタを元に戻す */
  357.     EMDeCross();
  358.     return TRUE;
  359. }
  360.  
  361. /******************************************************************************
  362.  *    paintPen():    ペンでのペイント処理
  363.  ******************************************************************************
  364.  *    引数:    ComVal *pcv    共通変数へのポインタ
  365.  *        LPoint lpt    マウスレフトダウン時の座標
  366.  */
  367. void paintPen(ComVal *pcv, LPoint lpt)
  368. {
  369.     Point pt, npt, opt, penSize[2];
  370.     Rect rc;
  371.  
  372.     /* UNDOのためにデータをセーブする */
  373.     saveDataForUndo(pcv);
  374.  
  375.     penSize[0] = pcv->penSize;
  376.     penSize[1].x_y = 0;
  377.  
  378.     /* ウィンドウの範囲になるよう調節する */
  379.     pt.x_y = lpt;
  380.     ajustPoint(&pt, penSize, &pcv->pictSize);
  381.     lpt = pt.x_y;
  382.  
  383.     rc.l.l_t = lpt;
  384.     rc.l.r_b = lpt;
  385.  
  386.     /* ビッツを使用するためにメモリをロックする */
  387.     GMLockBits(pcv->offBitsHdl[pcv->offIdx]);
  388.  
  389.     /* オフスクリーン用グラフをカレントグラフにする */
  390.     GMSetGraph(&pcv->offGraph);
  391.     pcv->offGraph.bmap = &(*pcv->offBitsHdl[pcv->offIdx])->bmap;
  392.  
  393.     GMPenSize(pcv->penSize.x_y);    /* ペンサイズを設定する        */
  394.     /* フォア/バックグラウンドカラーをセットする */
  395.     setFBColor(pcv);
  396.     /* マウスの押された場所を描画する */
  397.     drawFig(pcv, &rc);
  398.     /* ペンの座標の初期値を設定する */
  399.     GMMove(lpt);
  400.  
  401.     /* メインウィンドウをグラフィックタイプでカレントグラフにする */
  402.     setGraph(pcv->windowPtr, G_GRP);
  403.     /* ペンサイズの設定 */
  404.     OldPS.x_y = GMPenSize(pcv->penSize.x_y);
  405.     /* フォア/バックグラウンドカラーをセットする */
  406.     setFBColor(pcv);
  407.  
  408.     /* マウスの押された場所を描画する */
  409.     drawFig(pcv, &rc);
  410.     /* ペンの座標の初期値を設定する */
  411.     GMMove(lpt);
  412.  
  413.     opt.x_y = lpt;
  414.     npt.x_y = lpt;
  415.     while (EMLStill()) {
  416.         /* マウスが移動された場合のみ直線を表示する */
  417.         if (opt.x_y != npt.x_y) {
  418.             /* オフスクリーン用グラフをカレントグラフにする */
  419.             GMSetGraph(&pcv->offGraph);
  420.             pcv->offGraph.bmap = &(*pcv->offBitsHdl[pcv->offIdx])->bmap;
  421.             /* ウィンドウの範囲になるよう調節する */
  422.             ajustPoint(&npt, penSize, &pcv->pictSize);
  423.             /* オフスクリーンに描画する */
  424.             GMLine(npt.x_y);
  425.             /* メインウィンドウをグラフィックタイプで
  426.                カレントグラフにする */
  427.             setGraph(pcv->windowPtr, G_GRP);
  428.             /* メインウィンドウに描画する */
  429.             GMLine(npt.x_y);
  430.         }
  431.         opt = npt;
  432.         /* メインウィンドウをカレントグラフにする */
  433.         GMSetGraph(&pcv->windowPtr->graph);
  434.         /* マウスの現在位置を取得する */
  435.         npt.x_y = EMMSLoc();
  436.     }
  437.     /* ビッツのメモリをアンロックする */
  438.     GMUnlockBits(pcv->offBitsHdl[pcv->offIdx]);
  439.  
  440.     /* フォア/バックグラウンドカラーを元に戻す */
  441.     GMForeColor(OldFC);
  442.     GMBackColor(OldBC);
  443.     /* ペンモードを元に戻す */
  444.     GMPenMode(OldPM);
  445.     /* ペンサイズを元に戻す */
  446.     GMPenSize(OldPS.x_y);
  447.  
  448.     /* 描画終了処理 */
  449.     if (!pcv->editFlag)        /* まだ編集されてないか?    */
  450.         pcv->editFlag = TRUE;    /* 編集フラグをセットする    */
  451. }
  452.  
  453. /******************************************************************************
  454.  *    paintOfDomain():    指定された点と同じ色の領域の塗りつぶし
  455.  ******************************************************************************
  456.  *    引数:    ComVal *pcv    共通変数へのポインタ
  457.  *        LPoint lpt    マウスレフトダウン時の座標
  458.  */
  459. void paintOfDomain(ComVal *pcv, LPoint lpt)
  460. {
  461.     int errCode;
  462.     Rect rc;
  463.     Region **rgnHdl;
  464.  
  465.     /* 使用するリージョンハンドルを取得する */
  466.     rgnHdl = GMNewRgn();
  467.     if (rgnHdl == NULL) {
  468.         DMError(D_CONFIRM, "メモリが確保できません。");
  469.         return;
  470.     }
  471.  
  472.     /* UNDOのためにデータをセーブする */
  473.     saveDataForUndo(pcv);
  474.  
  475.     /* ビッツを使用するためにハンドルをロックする */
  476.     GMLockBits(pcv->offBitsHdl[pcv->offIdx]);
  477.  
  478.     /* 待ち状態を示すマウスポインタを表示する */
  479.     EMEnCross();
  480.     /* オフスクリーン用グラフをカレントグラフにする */
  481.     GMSetGraph(&pcv->offGraph);
  482.     pcv->offGraph.bmap = &(*pcv->offBitsHdl[pcv->offIdx])->bmap;
  483.  
  484.     /* 同じ色の点の領域をリージョンに変換する */
  485.     errCode = GMPaintRgn(rgnHdl, pcv->offGraph.bmap, lpt);
  486.     if (errCode < 0) {
  487.         GMDisposeRgn(rgnHdl);    /* リージョンハンドルを解放する    */
  488.         /* ビッツハンドルをアンロックする */
  489.         GMUnlockBits(pcv->offBitsHdl[pcv->offIdx]);
  490.         /* 待ち状態を示すマウスポインタを元に戻す */
  491.         EMDeCross();
  492.         DMError(D_CONFIRM, "図形が複雑すぎて枠のデータを\r"
  493.                    "作成できません。");
  494.         return;
  495.     }
  496.     /* リージョンを囲むレクタングルの座標をrcに設定する */
  497.     rc = (*rgnHdl)->bounds;
  498.     /* フォア/バックグラウンドカラーをセットする */
  499.     setFBColor(pcv);
  500.     /* 領域を塗りつぶす */
  501.     GMFillRgn(rgnHdl);
  502.  
  503.     /* 待ち状態を示すマウスポインタを元に戻す */
  504.     EMDeCross();
  505.  
  506.     /* メインウィンドウをグラフィックタイプでカレントグラフにする */
  507.     setGraph(pcv->windowPtr, G_GRP);
  508.  
  509.     /* オフスクリーンからコピーして描画する */
  510.     GMTransImg(&(*pcv->offBitsHdl[pcv->offIdx])->bmap, pcv->windowPtr->graph.bmap, &rc, &rc);
  511.  
  512.     /* ビッツハンドルをアンロックする */
  513.     GMUnlockBits(pcv->offBitsHdl[pcv->offIdx]);
  514.  
  515.     /* 描画終了処理 */
  516.     if (!pcv->editFlag)        /* まだ編集されてないか?    */
  517.         pcv->editFlag = TRUE;    /* 編集フラグをセットする    */
  518.  
  519.     GMDisposeRgn(rgnHdl);        /* リージョンハンドルを解放する    */
  520. }
  521.  
  522. /******************************************************************************
  523.  *    paintBrush():    ブラシでのペイント処理
  524.  ******************************************************************************
  525.  *    引数:    ComVal *pcv    共通変数へのポインタ
  526.  *        LPoint lpt    マウスレフトダウン時の座標
  527.  */
  528. void paintBrush(ComVal *pcv, LPoint lpt)
  529. {
  530.     int stat;
  531.     BitImg *wPtr;
  532.     Point npt, opt, dpt[2];
  533.     Rect rc;
  534.     Region **rgnHdl;
  535.  
  536.     /* 使用するリージョンハンドルを取得する */
  537.     rgnHdl = GMNewRgn();
  538.     if (rgnHdl == NULL) {
  539.         DMError(D_CONFIRM, "メモリが確保できません。");
  540.         return;
  541.     }
  542.  
  543.     /* UNDOのためにデータをセーブする */
  544.     saveDataForUndo(pcv);
  545.  
  546.     /* ビッツを使用するためにハンドルをロックする */
  547.     GMLockBits(pcv->offBitsHdl[pcv->offIdx]);
  548.     GMLockBits(pcv->wkBitsHdl);
  549.  
  550.     /* ワーク用グラフをカレントグラフにする */
  551.     GMSetGraph(&pcv->wkGraph);
  552.     /* ビットマップをセットする */
  553.     pcv->wkGraph.bmap = &(*pcv->wkBitsHdl)->bmap;
  554.  
  555.     rc = brrect;
  556.     if (pcv->toolKind == 2) {
  557.         /* ブラシが選択されているとき */
  558.         wPtr = pcv->brushImg;
  559.         rc.d.right = pcv->brushSize.p.x;
  560.         rc.d.bottom = pcv->brushSize.p.y;
  561.  
  562.     } else {
  563.         /* マウスポインタを消しゴムに変える */
  564.         MSSetCsr(pcv->mousePtn);
  565.         /* 消しゴムが選択されているとき */
  566.         wPtr = (*pcv->eraserImg)->data + 16;
  567.     }
  568.     GMAPage(G_PAGE0);
  569.     /* ワークのビットマップにビットイメージを描く */
  570.     GMPutImg(wPtr, &rc);
  571.     /* ビットイメージをリージョンに変換する */
  572.     GMImgToRgn(rgnHdl, &(*pcv->wkBitsHdl)->bmap, &rc);
  573.  
  574.     stat = GMEmptyRgn(rgnHdl);
  575.     if (stat == 1)
  576.         /* ヌルリージョンなら何もしないで終了する */
  577.         goto errend;
  578.  
  579.     opt.x_y = lpt;
  580.     npt.x_y = lpt;
  581.     dpt[0].x_y = 0;
  582.     dpt[1].x_y = 0;
  583.     /* ブラシでペイントする */
  584.     brushing(pcv, rgnHdl, &opt, &npt, dpt);
  585.     while (EMLStill()) {
  586.         /* マウスが移動された場合のみブラシで描画する */
  587.         if (opt.x_y != npt.x_y)
  588.             /* ブラシでペイントする */
  589.             brushing(pcv, rgnHdl, &opt, &npt, dpt);
  590.         opt = npt;
  591.         /* メインウィンドウをカレントグラフにする */
  592.         GMSetGraph(&pcv->windowPtr->graph);
  593.         /* マウスの現在位置を取得する */
  594.         npt.x_y = EMMSLoc();
  595.     }
  596.     /* 描画終了処理 */
  597.     if (!pcv->editFlag)        /* まだ編集されてないか?    */
  598.         pcv->editFlag = TRUE;    /* 編集フラグをセットする    */
  599. errend:
  600.     /* ビッツハンドルをアンロックする */
  601.     GMUnlockBits(pcv->offBitsHdl[pcv->offIdx]);
  602.     GMUnlockBits(pcv->wkBitsHdl);
  603.  
  604.     GMDisposeRgn(rgnHdl);        /* リージョンハンドルを解放する    */
  605.  
  606.     /* ペンサイズを元に戻す */
  607.     GMPenSize(OldPS.x_y);
  608.  
  609.     if (pcv->toolKind == 3)
  610.         /* マウスポインタを元に戻す */
  611.         MSInitCsr();
  612. }
  613.  
  614. /******************************************************************************
  615.  *    brushing():    ブラシでのペイント処理
  616.  ******************************************************************************
  617.  *    引数:    ComVal *pcv    共通変数へのポインタ
  618.  *        Region **rgnHdl    ブラシのリージョンハンドル
  619.  *        Point *opt    前回のマウスレフトダウン時の座標へのポインタ
  620.  *        Point *npt    今回のマウスレフトダウン時の座標へのポインタ
  621.  *        Point *dpt    ペンサイズの配列へのポインタ
  622.  */
  623. void brushing(ComVal *pcv, Region **rgnHdl, Point *opt, Point *npt, Point *dpt)
  624. {
  625.     int i;
  626.     Point pt;
  627.     LPoint lpt;
  628.     Region **rgnHdl2, **subRgnHdl;
  629.  
  630.     rgnHdl2 = GMNewRgn();
  631.     if (rgnHdl2 == NULL) {
  632.         DMError(D_CONFIRM, "メモリが確保できません。");
  633.         return;
  634.     }
  635.     subRgnHdl = GMNewRgn();
  636.     if (subRgnHdl == NULL) {
  637.         GMDisposeRgn(rgnHdl2);    /* リージョンハンドルを解放する    */
  638.         DMError(D_CONFIRM, "メモリが確保できません。");
  639.         return;
  640.     }
  641.  
  642.     /* 前回ポイントと今回ポイントの座標をウィンドウ内になるよう調節する */
  643.     ajustPoint(npt, dpt, &pcv->pictSize);
  644.     ajustPoint(opt, dpt, &pcv->pictSize);
  645.  
  646.     /* ブラシリージョンの位置を設定する */
  647.     if (pcv->toolKind == 2) {
  648.         /* ブラシが選択されているとき */
  649.         pt.p.x = opt->p.x - (pcv->brushSize.p.x / 2);
  650.         pt.p.y = opt->p.y - (pcv->brushSize.p.y / 2);
  651.     } else {
  652.         /* 消しゴムが選択されているとき*/
  653.         pt.p.x = opt->p.x - 8;
  654.         pt.p.y = opt->p.y - 8;
  655.     }
  656.     GMMoveRgn(rgnHdl, pt.x_y);
  657.  
  658.     pt.p.x = npt->p.x - opt->p.x;
  659.     pt.p.y = npt->p.y - opt->p.y;
  660.     if (pt.x_y != 0) {
  661.         GMSlidedRgn(rgnHdl2, rgnHdl, pt.x_y);
  662.         /* サブウィンドウのリージョン部分を除いた新たなリージョンを
  663.            作成する */
  664.         /* メインウィンドウをカレントグラフにする */
  665.         GMSetGraph(&pcv->windowPtr->graph);
  666.         lpt = GMGlobalToLocal(0);
  667.         for (i = 0; i < SUBMAX; i++)
  668.             /* サブウィンドウが表示されていたら */
  669.             if (pcv->subwinPtr[i] != NULL) {
  670.                 /* サブウィンドウのリージョンをコピーして */
  671.                 GMCopyRgn(subRgnHdl, pcv->subRgnHdl[i]);
  672.                 /* 座標をローカル座標系に変換する */
  673.                 GMSlideRgn(subRgnHdl, lpt);
  674.                 /* 新たなリージョンを求める */
  675.                 GMDiffRgn(rgnHdl2, rgnHdl2, subRgnHdl);
  676.             }
  677.     } else
  678.         /* 座標に変化がない(LDOWN の初回)はDOWN時の座標に描画するだけ */
  679.         GMCopyRgn(rgnHdl2, rgnHdl);
  680.  
  681.     /* オフスクリーン用グラフをカレントグラフにする */
  682.     GMSetGraph(&pcv->offGraph);
  683.     pcv->offGraph.bmap = &(*pcv->offBitsHdl[pcv->offIdx])->bmap;
  684.  
  685.     if (pcv->toolKind == 3) {
  686.         /* 消しゴムが選択されているときはカラー番号は15に固定*/
  687.         GMForeColor(15);    /* 消しゴムのパレット番号セット*/
  688.         GMPenMode(G_PSET);
  689.     } else
  690.         /* フォア/バックグラウンドカラーをセットする */
  691.         setFBColor(pcv);
  692.     /* オフスクリーンにリージョンを描画する */
  693.     GMFillRgn(rgnHdl2);
  694.     /* メインウィンドウをグラフィックタイプでカレントグラフにする */
  695.     setGraph(pcv->windowPtr, G_GRP);
  696.     if (pcv->toolKind == 3) {
  697.         /* 消しゴムが選択されているときはカラー番号は15に固定*/
  698.         /* 消しゴムのパレット番号セット*/
  699.         OldFC = GMForeColor(15);
  700.         OldBC = GMBackColor(15);
  701.         OldPM = GMPenMode(G_PSET);
  702.     } else
  703.         /* フォア/バックグラウンドカラーをセットする */
  704.         setFBColor(pcv);
  705.     /* メインウィンドウにもリージョンを描画する */
  706.     GMFillRgn(rgnHdl2);
  707.  
  708.     /* フォア/バックグラウンドカラーを元に戻す */
  709.     GMForeColor(OldFC);
  710.     GMBackColor(OldBC);
  711.     /* ペンモードを元に戻す */
  712.     GMPenMode(OldPM);
  713.  
  714.     GMDisposeRgn(subRgnHdl);    /* リージョンハンドルを解放する    */
  715.     GMDisposeRgn(rgnHdl2);
  716. }
  717.  
  718. /******************************************************************************
  719.  *    dispEseDlg():    疑似ダイアログを表示する
  720.  ******************************************************************************
  721.  *    引数:    ComVal *pcv    共通変数へのポインタ
  722.  *        int dmode    = 0: ファイル入出力疑似ダイアログ
  723.  *                = 1: 絵のサイズ設定疑似ダイアログ
  724.  */
  725. void dispEseDlg(ComVal *pcv, int dmode)
  726. {
  727.     static Rect rcFile = { 26, 40, 318, 70 };
  728.     static Rect rcGCntrol = { 26, 40, 192, 88 };
  729.     static Rect rcButton = { 234, 79, 314, 109 };
  730.  
  731.     /* メインウィンドウをテキストタイプでカレントグラフにする */
  732.     setGraph(pcv->windowPtr, G_TXT);
  733.  
  734.     /* 疑似ダイアログを表示する */
  735.     GMScrewRect(&rcFdlg);
  736.  
  737.     /* 2ページのみ使用する */
  738.     GMAPage(G_ALLPAGE);        /* アクセスページを全ページにする */
  739.     /* フォアグラウンドカラーを黒にする */
  740.     OldFC = GMForeColor(G_BLACK);
  741.     /* バックグラウンドカラーを白にする */
  742.     OldBC = GMBackColor(G_WHITE);
  743.     /* ペンモードをPSETに設定する */
  744.     OldPM = GMPenMode(G_PSET);
  745.     /* ペンサイズを(1,1)に設定する */
  746.     OldPS.x_y = GMPenSize(LONGWORD(1, 1));
  747.     /* フォントモードのセット */
  748.     OldFM = GMFontMode(G_PSET);
  749.  
  750.     if (dmode == 0) {        /* ファイル疑似ダイアログ */
  751.         /* ファイル名入力用のレクタングルを表示する */
  752.         GMShadowRect(&rcFile);
  753.  
  754.         /* バックグラウンドカラーをライトグレーにする */
  755.         GMBackColor(G_LGRAY);
  756.         /* ボタンのレクタングルを表示する */
  757.         GMShadowRect(&rcButton);
  758.  
  759.         /* 文字を描画 */
  760.         if (pcv->fileMode == 2)
  761.             GMShadowStrZ("読み込みファイル名", LONGWORD(26, 24));
  762.         else if (pcv->fileMode == 1)
  763.             GMShadowStrZ("保存ファイル名", LONGWORD(26, 24));
  764.  
  765.         /* アクセスページを0と1ページにする */
  766.         GMAPage(G_PAGE0 | G_PAGE1);
  767.         GMBackColor(G_WHITE);    /* バックグラウンドカラーを白にする */
  768.         /* テキストの文字列を描画する */
  769.         TMUpDate(pcv->fTEditHdl, &rcView);
  770.     } else {            /* 絵のサイズの疑似ダイアログ    */
  771.  
  772.         /* バックグラウンドカラーをライトグレーにする */
  773.         GMBackColor(G_LGRAY);
  774.         /* コントロールのレクタングルを表示する */
  775.         GMShadowRect(&rcGCntrol);
  776.         /* ボタンのレクタングルを表示する */
  777.         GMShadowRect(&rcButton);
  778.  
  779.         /* 文字を描画 */
  780.         GMShadowStrZ("絵のサイズの設定", LONGWORD(26, 24));
  781.         /* 文字を描画 */
  782.         GMShadowStrZ("X", LONGWORD(30, 46));
  783.         /* 文字を描画 */
  784.         GMShadowStrZ("Y", LONGWORD(30, 69));
  785.         /* アクセスページを0と1ページにする */
  786.         GMAPage(G_PAGE0 | G_PAGE1);
  787.         CMShow(pcv->adjBtnHdl[0]);
  788.         CMShow(pcv->adjBtnHdl[1]);
  789.     }
  790.     /* コントロールを描画する */
  791.     CMDraw(pcv->windowPtr);
  792.  
  793.     /* フォントモードを元に戻す */
  794.     GMFontMode(OldFM);
  795.     /* フォアグラウンドカラーを元に戻す */
  796.     GMForeColor(OldFC);
  797.     /* バックグラウンドカラーを元に戻す */
  798.     GMBackColor(OldBC);
  799.     /* ペンモードを元に戻す */
  800.     GMPenMode(OldPM);
  801.     /* ペンサイズを元に戻す */
  802.     GMPenSize(OldPS.x_y);
  803. }
  804.  
  805. /******************************************************************************
  806.  *    newPicture():    新規編集処理(消しゴムで[NEW]ボタンが押されたとき)
  807.  ******************************************************************************
  808.  *    引数:    ComVal *pcv    共通変数へのポインタ
  809.  */
  810. void newPicture(ComVal *pcv)
  811. {
  812.     int num;
  813.  
  814.     /* ツール選択ウィンドウをカレントグラフにする */
  815.     GMSetGraph(&pcv->subwinPtr[TOOL]->win.graph);
  816.  
  817.     GMAPage(G_PAGE0 | G_PAGE1);    /* アクセスページを0と1ページにする */
  818.     num = DMError(D_YESNO, "絵を消去します。\r"
  819.                    "よろしいですか?");
  820.     if (num == 1) {
  821.         GMLockBits(pcv->offBitsHdl[pcv->offIdx]);
  822.         /* ビッツのビットイメージ領域をパレットNo.15でクリア */
  823.         memset((*pcv->offBitsHdl[pcv->offIdx])->data, 0xff, (size_t)(*pcv->offBitsHdl[pcv->offIdx])->size);
  824.  
  825.         /* メインウィンドウをグラフィックタイプでカレントグラフにする */
  826.         setGraph(pcv->windowPtr, G_GRP);
  827.  
  828.         /* ウィンドウ全体を描き直す */
  829.         pcv->offGraph.bmap = &(*pcv->offBitsHdl[pcv->offIdx])->bmap;
  830.         GMTransImg(&(*pcv->offBitsHdl[pcv->offIdx])->bmap, pcv->windowPtr->graph.bmap, &pcv->pictSize, &pcv->pictSize);
  831.         /* ビッツをアンロックする */
  832.         GMUnlockBits(pcv->offBitsHdl[pcv->offIdx]);
  833.         pcv->editFlag = FALSE;    /* 編集フラグをクリアする    */
  834.     }
  835. }
  836.  
  837. /******************************************************************************
  838.  *    saveDataForUndo():    アンドゥ用にデ-タをセーブする
  839.  ******************************************************************************
  840.  *    引数:    ComVal *pcv    共通変数へのポインタ
  841.  */
  842. void saveDataForUndo(ComVal *pcv)
  843. {
  844.     unsigned short idx;
  845.  
  846.     if (pcv->undoFlag) {
  847.         /* 現在使用中のビッツハンドルではないほうのインデックスを取得する */
  848.         idx = (pcv->offIdx | 0xfffe) ^ 0xffff;
  849.         /* ビッツをロックする */
  850.         GMLockBits(pcv->offBitsHdl[pcv->offIdx]);
  851.         GMLockBits(pcv->offBitsHdl[idx]);
  852.         /*pcv->offGraph.bmap = &(*pcv->offBitsHdl[idx])->bmap;*/
  853.         /* 現在使用中のバッファからUNDO用のバッファにコピー */
  854.         GMCopy(&(*pcv->offBitsHdl[pcv->offIdx])->bmap, &(*pcv->offBitsHdl[idx])->bmap, &pcv->pictSize, &pcv->pictSize, G_PSET, NULL);
  855.         GMUnlockBits(pcv->offBitsHdl[idx]);
  856.         GMUnlockBits(pcv->offBitsHdl[pcv->offIdx]);
  857.     }
  858. }
  859.  
  860. /******************************************************************************
  861.  *    execUndo():    アンドゥを実行する
  862.  ******************************************************************************
  863.  *    引数:    ComVal *pcv    共通変数へのポインタ
  864.  */
  865. void execUndo(ComVal *pcv)
  866. {
  867.     unsigned short idx;
  868.  
  869.     if (!pcv->editFlag)        /* まだ編集されてないか?    */
  870.         return;
  871.  
  872.     /* UNDO機能がONならば処理を行う */
  873.     if (pcv->undoFlag) {
  874.         /* メインウィンドウをグラフィックタイプでカレントグラフにする */
  875.         setGraph(pcv->windowPtr, G_GRP);
  876.         /* 現在使用中のビッツハンドルではないほうのインデックスを取得する */
  877.         idx = (pcv->offIdx | 0xfffe) ^ 0xffff;
  878.         /* ビッツをロックする */
  879.         GMLockBits(pcv->offBitsHdl[idx]);
  880.         pcv->offGraph.bmap = &(*pcv->offBitsHdl[idx])->bmap;
  881.  
  882.         /* 現在UNDO用のバッファからウィンドウにコピー */
  883.         GMTransImg(&(*pcv->offBitsHdl[idx])->bmap, pcv->windowPtr->graph.bmap, &pcv->pictSize, &pcv->pictSize);
  884.         /* ビッツをアンロックする */
  885.         GMUnlockBits(pcv->offBitsHdl[idx]);
  886.  
  887.         /* ビッツインデックスを入れ換える */
  888.         pcv->offIdx = idx;
  889.  
  890.         /* ルーペウィンドウが表示されていたら */
  891.         if (pcv->subwinPtr[LUPE] != NULL)
  892.             /* ルーペウィンドウの内部を描く */
  893.             drawLupeRect(pcv);
  894.     }
  895. }
  896.